# [五] Bean的实例化-后置处理器
# Spring 初始化核心流程
spring容器初始化的核心方法AbstractApplicationContext#refresh ,
├─
refresh Spring 初始化核心流程入口│ ├─
prepareRefresh ① 准备此上下文用于刷新,设置启动时间和active标志,初始化属性│ ├─
obtainFreshBeanFactory ② 创建 BeanFactory│ ├─
prepareBeanFactory ③ 设置 BeanFactory 的基本属性│ ├─
postProcessBeanFactory ④ 子类处理自定义的BeanFactoryPostProcess│ ├─
invokeBeanFactoryPostProcessors ⑤ B本节主要跟踪的源码流程│ ├─
registerBeanPostProcessors ⑥ 本节主要跟踪的源码流程│ ├─
initMessageSource ⑦ 初始化上下文中的资源文件,如国际化文件的处理等│ ├─
initApplicationEventMulticaster ⑧ 初始化上下文的事件传播器│ ├─
onRefresh ⑨ 给子类扩展初始化其他Bean,springboot 中用来做内嵌 tomcat 启动│ ├─
registerListeners ⑩ 在所有bean中查找监听 bean,然后注册到广播器中│ ├─
finishBeanFactoryInitialization ⑪ 初始化所有的单例Bean、ioc、BeanPostProcessor的执行、Aop入口│ └─
finishRefresh ⑫ 完成刷新过程,发布相应的事件
# invokeBeanFactoryPostProcessors 方法
invokeBeanFactoryPostProcessors
⑤invokeBeanFactoryPostProcessors
方法,负责激活各种 BeanFactory 处理器,以及两个核心接口的调用:
BeanDefinitionRegistryPostProcessor
- 实际完成了对其实现类中
postProcessBeanDefinitionRegistry
方法的调用,完成对BeanDefinition的新增、修改;
- 实际完成了对其实现类中
BeanFactoryPostProcessor
- 实际完成了对其实现类中
postProcessBeanFactory
方法的调用;
- 实际完成了对其实现类中
直接进入最终的
invokeBeanFactoryPostProcessors()
方法,类文件: org.springframework.context.support.
AbstractApplicationContext
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 获取实现了BeanDefinitionRegistryPostProcessor接口的所有类的BeanDefinition对象的beanName
// 1、最先调用的是实现了 PriorityOrdered 接口的所有BeanDefinitionRegistryPostProcessor
// 中的 postProcessBeanDefinitionRegistry的方法
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 判断是否实现了排序接口 PriorityOrdered
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序,就是用List中的sort排序,通过Comparator来进行
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 调用过程
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 调用完清空
currentRegistryProcessors.clear();
// 2、其次调用的是实现了 Ordered 接口的所有BeanDefinitionRegistryPostProcessor
// 中的 postProcessBeanDefinitionRegistry的方法
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//判断是否是实现的Ordered接口
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 3、最后调用的是没实现排序接口的所有实现BeanDefinitionRegistryPostProcessor接口
// 中的 postProcessBeanDefinitionRegistry的方法
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 调用 postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 获取实现了BeanFactoryPostProcessor接口的类,获取beanDefinition的名称
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
// 实现了PriorityOrdered接口的
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// 实现了Ordered接口的
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
// 没实现接口的
nonOrderedPostProcessorNames.add(ppName);
}
}
// 排序
// 先调用实现了 PriorityOrdered接口的 BeanFactoryPostProcessors
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 调用
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 接着调用实现了 Ordered接口的 BeanFactoryPostProcessors
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
进入
invokeBeanDefinitionRegistryPostProcessors()
方法的调用过程,
类文件: org.springframework.context.support.
PostProcessorRegistrationDelegate
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
// 拿到所有实现了PriorityOrdered 接口的类
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
// 调用它的postProcessBeanFactory方法
postProcessor.postProcessBeanFactory(beanFactory);
}
}
至此,⑤ 调用激活所有实现了BeanDefinitionRegistryPostProcessor接口中的两个方法,执行过程完成。
# registerBeanPostProcessors 方法
registerBeanPostProcessors
⑥registerBeanPostProcessors
方法,主要是针对实现BeanPostProcessor
接口的类调用和实例化过程。
BeanPostProcessor
接口类型实例是针对某种特定功能的埋点,在这个点会根据接口类型来过滤掉不关注这个点的其他类,只有真正关注的类才会在这个点进行相应的功能实现。
进入⑥
registerBeanPostProcessors()
方法,
类文件: org.springframework.context.support.
PostProcessorRegistrationDelegate
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//拿到工程里面所有实现了BeanPostProcessor接口的类,获取到BeanDefinition的名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//当一个bean是在BeanPostProcessor实例化期间创建的,也就是说当一个 bean不能被所有的beanpostprocessor处理时,
//注册BeanPostProcessorChecker,记录信息信息
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 提前实例化 BeanPostProcessor 类型的 bean,然后对 bean 进行排序
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// getBean是实例化方法,后面我们在讲bean实例化过程是会着重讲到
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
// 判断类型是否是 MergedBeanDefinitionPostProcessor,如果是则代码是内部使用的
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 首先,注册实现 priorityor 的 beanpostprocessor。
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//注册到BeanFactory中
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 然后,注册实现 Ordered 的 BeanPostProcessors。
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 接着注册所有常规的 beanpostprocessor。
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后,重新注册所有的内部 beanpostprocessor。
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 将检测内部 bean的后处理器重新注册为 applicationlistener,
// 将它移到处理器链的末端(用于获取代理等)。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
知识点
beanFactory.getBeanPostProcessorCount()
会得到默认容器中注册的 BeanPostProcessor 个数,实际就是调用
List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>()
的size()
方法,默认的容器注册的 BeanPostProcessor 有:
- ApplicationContextAwarePostProcessor
- ApplicationListenerDetector
- ConfigurationClassPostProcessor
- PostProcessorRegistrationDelegate
进入
registerBeanPostProcessors()
方法,注册过程
类文件: org.springframework.context.support.
PostProcessorRegistrationDelegate
/**
* 注册当前的 BeanPostProcessor
*/
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
// 添加到List<BeanPostProcessor> beanPostProcessors
beanFactory.addBeanPostProcessor(postProcessor);
}
}
知识点
⑤invokeBeanFactoryPostProcessors
和⑥registerBeanPostProcessors
两个方法的处理流程基本一致,都分别对实现接口的类实例化调用:
- 首先对实现
PriorityOrdered
接口的 beanPostProcessors 排序调用 - 其次对实现
Ordered
接口的 beanPostProcessors 排序调用 - 最后对
没有实现排序
接口的 beanPostProcessors 调用
# BeanPostProcessor
BeanPostProcessor有两个方法,postProcessBeforeInitialization
和postProcessAfterInitialization
。它们分别在任何bean初始化回调之前或之后执行(例如InitializingBean的afterPropertiesSet方法或自定义init-method方法之前或者之后), 在这个时候该bean的属性值已经填充完成了,并且我们返回的bean实例可能已经是原始实例的包装类型了。例如返回一个FactoryBean
。
# InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor
继承自BeanPostProcessor
接口。主要多提供了以下三个方法:
- postProcessBeforeInstantiation:该方法是在Bean实例化目标对象之前调用,返回的Bean对象可以代理目标,从而有效的阻止了目标Bean的默认实例化。
- postProcessAfterInstantiation:该方法执行在通过构造函数或工厂方法在实例化bean之后但在发生Spring属性填充(通过显式属性或自动装配)之前执行操作。这是在Spring的自动装配开始之前对给定的bean实例执行自定义字段注入的理想回调。如果该方法返回false,那么它会阻断后续InstantiationAwareBeanPostProcessor后置处理器的执行,并且会阻止后续属性填充的执行逻辑。
- postProcessPropertyValues:在工厂将给定属性值应用于给定bean之前,对它们进行后处理。允许检查是否满足所有依赖关系,例如基于bean属性设置器上的“ Required”注解。还允许替换要应用的属性值,通常是通过基于原始PropertyValues创建新的MutablePropertyValues实例,添加或删除特定值来实现。
# SmartInstantiationAwareBeanPostProcessor
智能实例化Bean的后处理器,主要提供了三个方法:
- predictBeanType:预测从此处理器的postProcessBeforeInstantiation回调最终返回的bean的类型。
- determineCandidateConstructors:确定合适的实例化Bean的构造函数。
- getEarlyBeanReference:获取提早暴露的Bean的引用,提早暴露的Bean就是只完成了实例化,还未完成属性赋值和初始化的Bean。
# MergedBeanDefinitionPostProcessor
合并Bean的定义信息的后处理方法,该方法是在Bean的实例化之后设置值之前调用。
# beanPostProcessors 答疑
问题
为什么⑤invokeBeanFactoryPostProcessors
方法,在② 执行之后呢?
参考答案
因为并不是所有功能都配置在xml文件中,有些业务场景需要在程序运行时,动态的调用或者修改beanDefinition。实际上就是Spring初始化时,自动调用实现了BeanDefinitionRegistryPostProcessor
接口中的postProcessBeanDefinitionRegistry
、postProcessBeanFactory
个方法。
问题
为什么⑥registerBeanPostProcessors()
方法中,会提前实例化BeanPostProcessor
类型的 bean?
参考答案
因为 bean在实例化过程中进行依赖注入,有可能引用到BeanPostProcessor
类型的 bean。